package com.hopechart.micro.config;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.hopechart.micro.util.DataSourceUtil;

/**
 * <p>
 *     <br/>数据源配置
 * </p>
 * @author daijiang@hopechart.com
 * @date 2017-10-30 09:00:47
 * @copyright 杭州鸿泉数字设备有限公司
 * @version V1.0.0
 */
@Component
@EnableTransactionManagement
@ConfigurationProperties(prefix = "datasource.master", ignoreUnknownFields = true)
@MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {

	@Autowired
	private MybatisProperties properties;

	@Autowired
	private CommonDataSourceConfig commonDataSourceConfig;

	static final String PACKAGE = "com.hopechart.micro.domain.mapper.master";
	static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml";
	static final String TYPE_ALIASES_PACKAGE = "com.hopechart.micro.domain.entities.master";

	private String url;

	private String username;

	private String password;

	private String driverClassName;

	private String dbType;


	/**
	 * @Primary 标志这个 Bean 如果在多个同类 Bean 候选时，该 Bean 优先被考虑。
	 * 多数据源配置的时候注意，必须要有一个主数据源，用 @Primary 标志该 Bean
	 */
    @Primary
    @Bean(name = "masterDataSource", initMethod = "init", destroyMethod = "close")
	public DataSource masterDataSource() {
		return DataSourceUtil.getDataSource(url, username, password, driverClassName, dbType, commonDataSourceConfig);
	}

	/**
	 * @Primary 标志这个 Bean 如果在多个同类 Bean 候选时，该 Bean 优先被考虑。
	 * 多数据源配置的时候注意，必须要有一个主数据源，用 @Primary 标志该 Bean
	 */
    @Bean(name = "masterTransactionManager")
	@Primary
	public DataSourceTransactionManager transactionManager() {
		return new DataSourceTransactionManager(masterDataSource());
	}

    /**
     * @Primary 标志这个 Bean 如果在多个同类 Bean 候选时，该 Bean 优先被考虑。
     * 多数据源配置的时候注意，必须要有一个主数据源，用 @Primary 标志该 Bean
     */
	@Primary
    @Bean(name = "masterSqlSessionFactory")
	public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource)
			throws Exception {
		final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(masterDataSource);
		sessionFactory.setConfiguration(properties.getConfiguration());
		sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MasterDataSourceConfig.MAPPER_LOCATION));
		sessionFactory.setTypeAliasesPackage(TYPE_ALIASES_PACKAGE);
		return sessionFactory.getObject();
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getDriverClassName() {
		return driverClassName;
	}

	public void setDriverClassName(String driverClassName) {
		this.driverClassName = driverClassName;
	}

	public String getDbType() {
		return dbType;
	}

	public void setDbType(String dbType) {
		this.dbType = dbType;
	}
}
